package com.nike.amoeba.viewmodel

import androidx.lifecycle.MutableLiveData
import com.blankj.utilcode.util.LogUtils
import com.blankj.utilcode.util.TimeUtils
import com.blankj.utilcode.util.ToastUtils
import com.google.gson.Gson
import com.nike.amoeba.base.MyBaseViewModel
import com.nike.amoeba.bean.DataBean
import com.nike.amoeba.bean.db.AssetBean
import com.nike.amoeba.bean.db.MainDrawerBean
import com.nike.amoeba.bean.db.TaskAssetBean
import com.nike.amoeba.bean.db.TaskStockBean
import com.nike.amoeba.bean.db.TaskStockListBean
import com.nike.amoeba.ext.ASSET_IN
import com.nike.amoeba.network.REQUEST_SUCCESS
import com.nike.amoeba.network.apiService
import com.nike.amoeba.network.stateCallback.ListDataUiState
import io.reactivex.rxjava3.core.Flowable
import io.reactivex.rxjava3.disposables.CompositeDisposable
import io.reactivex.rxjava3.disposables.Disposable
import io.reactivex.rxjava3.schedulers.Schedulers
import io.reactivex.rxjava3.subjects.BehaviorSubject
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.Job
import kotlinx.coroutines.launch
import kotlinx.coroutines.withContext
import me.hgj.jetpackmvvm.callback.databind.FloatObservableField
import me.hgj.jetpackmvvm.callback.databind.StringObservableField
import me.hgj.jetpackmvvm.ext.requestNoCheck
import org.json.JSONObject

/**
 * @Author nike
 * @Date 2023/7/7 16:51
 * @Description
 */
class DownloadModel: MyBaseViewModel() {

    var progressText = StringObservableField("0%")

    var progress = FloatObservableField()

    var listAssetBean: MutableLiveData<ListDataUiState<TaskAssetBean>> = MutableLiveData()

    var listAssetBean2: MutableLiveData<DataBean> = MutableLiveData()
    var listStockBean2: MutableLiveData<DataBean> = MutableLiveData()

    var listStockBean: MutableLiveData<ListDataUiState<TaskStockBean>> = MutableLiveData()

    var listBean: MutableLiveData<ListDataUiState<MainDrawerBean>> = MutableLiveData()

    var disposable: Disposable? = null

    // 定义一个 CompositeDisposable 实例
    private var compositeDisposable = CompositeDisposable()

    // 定义 BehaviorSubject
    private val dataSubject: BehaviorSubject<List<AssetBean>> = BehaviorSubject.create()

    private val viewModelJob = Job()

    private val viewModelScope = CoroutineScope(Dispatchers.Main + viewModelJob)

    fun onRequest() {
        requestNoCheck({ apiService.stockTakeList(null) }, {
            if (it.code == REQUEST_SUCCESS){
                val data = it.data
                if (data != null){
                    viewModelScope.launch(Dispatchers.IO) {
                        data.forEachIndexed(){index, bean ->
                            bean.userId = userId
                            bean.companyId = companyId
                            bean.type = ASSET_IN
                            bean.createDate = TimeUtils.getNowString()
                            val split = bean.StartDate!!.split("/")
                            bean.StartDate = split.getOrNull(2)?.let { year ->
                                split.getOrNull(1)?.let { month ->
                                    split.getOrNull(0)?.let { day ->
                                        "$year-$month-$day"
                                    }
                                }
                            } ?: bean.StartDate

                            val splitEndDate = bean.EndDate!!.split("/")
                            bean.EndDate = splitEndDate.getOrNull(2)?.let { year ->
                                splitEndDate.getOrNull(1)?.let { month ->
                                    splitEndDate.getOrNull(0)?.let { day ->
                                        "$year-$month-$day"
                                    }
                                }
                            } ?: bean.EndDate
                            //存储数据库
                            taskAssetDao.add(bean)
                            stockTakeListAsset(bean, userId!!, companyId!!, null)
                        }
                        withContext(Dispatchers.Main) {
                            listAssetBean.value = ListDataUiState(
                                isSuccess = true,
                                pageSize = it.count
                            )
                        }
                    }
                }
            }

        }, {
            //请求失败 网络异常回调在这里
            loadingChange.dismissDialog
            ToastUtils.showShort(it.throwable!!.message)
            LogUtils.e(it.throwable)
        }, false)
    }

    private fun stockTakeListAsset(bean: TaskAssetBean, userId: String, companyID: String, code: String?) {
        var stocktakeno = bean.Stocktakeno!!
        requestNoCheck({ apiService.stockTakeListAsset(stocktakeno, code!!) }, {
            val json = JSONObject(it.string())
            if (json.optInt("code") == REQUEST_SUCCESS) {
                val data = json.optJSONArray("data")
                if (data != null) {
                    disposable = Flowable.range(0, data.length())
                        .onBackpressureBuffer()
                        .flatMap({ index ->
                            val jsonObject = data.optJSONObject(index)
                            val just = Flowable.just(jsonObject)
                            just.flatMap({ jsonObject ->
                                val tag = jsonObject.optJSONObject("Tag")
                                val inventory = jsonObject.optJSONObject("Inventory")
                                val bean = AssetBean()

                                val pair = Pair(jsonObject, bean)
                                Flowable.fromCallable {
                                    val jsonObject = pair.first as JSONObject
                                    val bean = pair.second as AssetBean
                                    bean.id = tag.optString("userId")
                                    bean.OrderRoNo = stocktakeno
                                    bean.AssetNo = tag.optString("AssetNo")
                                    bean.LabelTag = tag.optString("LabelTag")
                                    bean.Remarks = tag.optString("remarks")
                                    bean.InventoryStatus = tag.optInt("InventoryStatus")
                                    bean.code = code!!
                                    if (inventory != null){
                                        bean.scanStatus = inventory.optInt("FoundStatus")
                                    }
                                    bean.userId = userId
                                    bean.companyId = companyID

                                    bean.data = jsonObject.toString()

                                    bean
                                }.subscribeOn(Schedulers.io())
                            }, true, 1)
                        })
                        .subscribe { bean ->
                            viewModelScope.launch {
                                assetDao.add(bean)
                            }
                        }
                }
            }
        }, {
            //请求失败 网络异常回调在这里
            loadingChange.dismissDialog
            ToastUtils.showShort(it.throwable!!.message)
            LogUtils.e(it.throwable)
        }, false)
    }

    override fun onCleared() {
        super.onCleared()
        disposable?.dispose()
        compositeDisposable?.dispose()
        viewModelJob.cancel() // 在 ViewModel 销毁时取消所有协程
    }

    fun onWarehouse() {
        requestNoCheck({ apiService.getStockTakeList(null) }, {
            if (it.code == REQUEST_SUCCESS){
                val data = it.data
                if (data != null){
                    //删除当前用户的数据库
                    viewModelScope.launch(Dispatchers.IO) {
                        var allnum = 0
                        data.forEachIndexed(){index, bean ->
                            bean.userId = userId
                            bean.companyId = companyId
                            taskStockDao.add(bean)
                            allnum += bean.DataNum
                            getStockTakeDetail(bean.OrderNo!!, userId!!, companyId!!, null)
                        }
                        withContext(Dispatchers.Main) {
                            listStockBean.value = ListDataUiState(
                                isSuccess = if (data.size != 0) true else false,
                                pageSize = allnum
                            )
                        }
                    }
                }
            }

        }, {
            //请求失败 网络异常回调在这里
            loadingChange.dismissDialog
            ToastUtils.showShort(it.throwable!!.message)
            LogUtils.e(it.throwable)
        }, false)
    }

    private fun getStockTakeDetail(
        stocktakeno: String,
        userId: String,
        companyID: String,
        code: String?
    ) {
        requestNoCheck({ apiService.getStockTakeDetail(stocktakeno!!, code!!) }, {
            val json = JSONObject(it.string())
            if (json.optInt("code") == REQUEST_SUCCESS) {
                val data = json.optJSONObject("data")
                viewModelScope.launch(Dispatchers.IO) {
                    if (data != null){
                        val datalist = data.optJSONArray("datalist")
                        if (datalist != null && datalist.length() != 0) {
                            for (i in 0 until datalist.length()) {
                                val obj = datalist.optJSONObject(i)
                                obj.put("userId", userId)
                                obj.put("companyId", companyID)
                                obj.put("code", code)

                                val listStr = ArrayList<DataBean>()
                                val attributes = obj.optJSONObject("Attributes")
                                if (attributes != null){
                                    val keys: Iterator<String> = attributes.keys()
                                    while (keys.hasNext()) {
                                        var key = keys.next()
                                        val value: String = attributes.getString(key)
                                        val bean = DataBean()
                                        if (key.contains("InStorage-")) {
                                            key = key.substring(10)
                                        } else if (key.contains("OutStorage-")) {
                                            key = key.substring(11)
                                        }
                                        bean.Title = key
                                        bean.content = value
                                        listStr.add(bean)
                                    }
                                }
                                obj.put("content", Gson().toJson(listStr).toString())
                                val taskStockListBean = Gson().fromJson(obj.toString(), TaskStockListBean::class.java)
                                taskStockListDao.add(taskStockListBean)
                            }
                        }
                    }
                }
            }
        }, {
            //请求失败 网络异常回调在这里
            loadingChange.dismissDialog
            ToastUtils.showShort(it.throwable!!.message)
            LogUtils.e(it.throwable)
        }, false)
    }

    fun onModuleList() {
        requestNoCheck({ apiService.getModuleList() }, {
            if (it.code == REQUEST_SUCCESS){
                val bean = it.data
                if (bean != null){
                    var list = ArrayList<MainDrawerBean>()
                    synchronized(this){
                        viewModelScope.launch(Dispatchers.IO) {
                            val stockTake = bean.StockTake
                            if (!stockTake.isNullOrEmpty()){
                                stockTake.forEach {
                                    val drawerBean = MainDrawerBean()
                                    drawerBean.companyId = companyId
                                    drawerBean.userId = userId
                                    drawerBean.Type = it.Type
                                    drawerBean.Name = it.Name.toString()
                                    drawerBean.Code = it.Code.toString()
                                    drawerBean.Count = it.Count
                                    drawerBean.Total = it.TotalNum
                                    drawerBean.ParentType = 0
                                    mainDrawerDao.add(drawerBean)
                                    list.add(drawerBean)

                                    if (it.Type == 0){
                                        onStockTakeListRequest(it.Code)
                                    }else{
                                        onStockListRequest(it.Code)
                                    }
                                }
                            }

                            val stock = bean.Stock
                            if (!stockTake.isNullOrEmpty()){
                                stock?.forEach {
                                    val drawerBean = MainDrawerBean()
                                    drawerBean.companyId = companyId
                                    drawerBean.userId = userId
                                    drawerBean.Type = it.Type
                                    drawerBean.Name = it.Name.toString()
                                    drawerBean.Code = it.Code.toString()
                                    drawerBean.Count = it.Count
                                    drawerBean.ParentType = 1
                                    mainDrawerDao.add(drawerBean)

                                    drawerBean.ParentType = 2
                                    mainDrawerDao.add(drawerBean)
                                }
                            }


                            withContext(Dispatchers.Main) {
                                listBean.value = ListDataUiState(
                                    isSuccess = true,
                                    listData = list
                                )
                            }
                        }
                    }
                }
            }

        }, {
            //请求失败 网络异常回调在这里
            loadingChange.dismissDialog
            ToastUtils.showShort(it.throwable!!.message)
            LogUtils.e(it.throwable)
        }, false)
    }

    private fun onStockListRequest(code: String?) {
        requestNoCheck({ apiService.getStockTakeList(code!!) }, {
            if (it.code == REQUEST_SUCCESS){
                val data = it.data
                if (data != null){
                    viewModelScope.launch(Dispatchers.IO) {
                        data.forEachIndexed(){index, bean ->
                            bean.id = bean.userId
                            bean.userId = userId
                            bean.companyId = companyId
                            bean.code = code
                            taskStockDao.add(bean)
                            getStockTakeDetail(bean.OrderNo!!, userId!!, companyId!!, code)
                        }
                    }
                }
            }

        }, {
            //请求失败 网络异常回调在这里
            loadingChange.dismissDialog
            ToastUtils.showShort(it.throwable!!.message)
            LogUtils.e(it.throwable)
        }, false)
    }

    private fun onStockTakeListRequest(code: String?) {
        requestNoCheck({ apiService.stockTakeList(code!!) }, {
            if (it.code == REQUEST_SUCCESS){
                val data = it.data
                if (data != null){
                    viewModelScope.launch(Dispatchers.IO) {
                        data.forEachIndexed(){index, bean ->
                            bean.id = bean.userId
                            bean.userId = userId
                            bean.companyId = companyId
                            bean.type = ASSET_IN
                            bean.code = code!!
                            bean.createDate = TimeUtils.getNowString()
                            val split = bean.StartDate!!.split("/")
                            bean.StartDate = split.getOrNull(2)?.let { year ->
                                split.getOrNull(1)?.let { month ->
                                    split.getOrNull(0)?.let { day ->
                                        "$year-$month-$day"
                                    }
                                }
                            } ?: bean.StartDate

                            val splitEndDate = bean.EndDate!!.split("/")
                            bean.EndDate = splitEndDate.getOrNull(2)?.let { year ->
                                splitEndDate.getOrNull(1)?.let { month ->
                                    splitEndDate.getOrNull(0)?.let { day ->
                                        "$year-$month-$day"
                                    }
                                }
                            } ?: bean.EndDate
                            //存储数据库
                            taskAssetDao.add(bean)
                            stockTakeListAsset(bean, userId!!, companyId!!, code)
                        }
                    }
                }
            }

        }, {
            //请求失败 网络异常回调在这里
            loadingChange.dismissDialog
            ToastUtils.showShort(it.throwable!!.message)
            LogUtils.e(it.throwable)
        }, false)
    }

    fun onModuleList2() {
        requestNoCheck({ apiService.getModuleList() }, {
            if (it.code == REQUEST_SUCCESS){
                val bean = it.data
                if (bean != null){
                    var list = ArrayList<MainDrawerBean>()
                    synchronized(this){
                        viewModelScope.launch(Dispatchers.IO) {
                            val stockTake = bean.StockTake
                            if (!stockTake.isNullOrEmpty()){
                                stockTake.forEach {
                                    val drawerBean = MainDrawerBean()
                                    drawerBean.companyId = companyId
                                    drawerBean.userId = userId
                                    drawerBean.Type = it.Type
                                    drawerBean.Name = it.Name.toString()
                                    drawerBean.Code = it.Code.toString()
                                    drawerBean.Count = it.Count
                                    drawerBean.Total = it.TotalNum
                                    drawerBean.ParentType = 0
                                    mainDrawerDao.add(drawerBean)
                                    list.add(drawerBean)
//                                    if (it.Type == 0){
//                                        onStockTakeListRequest(it.Code)
//                                    }else{
//                                        onStockListRequest(it.Code)
//                                    }
                                }
                            }

                            val stock = bean.Stock
                            if (!stockTake.isNullOrEmpty()){
                                stock?.forEach {
                                    val drawerBean = MainDrawerBean()
                                    drawerBean.companyId = companyId
                                    drawerBean.userId = userId
                                    drawerBean.Type = it.Type
                                    drawerBean.Name = it.Name.toString()
                                    drawerBean.Code = it.Code.toString()
                                    drawerBean.Count = it.Count
                                    drawerBean.ParentType = 1
                                    mainDrawerDao.add(drawerBean)

                                    drawerBean.ParentType = 2
                                    mainDrawerDao.add(drawerBean)
                                }
                            }


                            withContext(Dispatchers.Main) {
                                listBean.value = ListDataUiState(
                                    isSuccess = true,
                                    listData = list
                                )
                            }
                        }
                    }
                }
            }

        }, {
            //请求失败 网络异常回调在这里
            loadingChange.dismissDialog
            ToastUtils.showShort(it.throwable!!.message)
            LogUtils.e(it.throwable)
        }, false)
    }

     fun onStockTakeListRequest2(code: String?, total: Int) : Boolean{
        requestNoCheck({ apiService.stockTakeList(code!!) }, {
            if (it.code == REQUEST_SUCCESS){
                val data = it.data
                if (data != null){
                    viewModelScope.launch(Dispatchers.IO) {
                        data.forEachIndexed(){index, bean ->
                            bean.id = bean.userId
                            bean.userId = userId
                            bean.companyId = companyId
                            bean.type = ASSET_IN
                            bean.code = code!!
                            bean.createDate = TimeUtils.getNowString()
                            val split = bean.StartDate!!.split("/")
                            bean.StartDate = split.getOrNull(2)?.let { year ->
                                split.getOrNull(1)?.let { month ->
                                    split.getOrNull(0)?.let { day ->
                                        "$year-$month-$day"
                                    }
                                }
                            } ?: bean.StartDate

                            val splitEndDate = bean.EndDate!!.split("/")
                            bean.EndDate = splitEndDate.getOrNull(2)?.let { year ->
                                splitEndDate.getOrNull(1)?.let { month ->
                                    splitEndDate.getOrNull(0)?.let { day ->
                                        "$year-$month-$day"
                                    }
                                }
                            } ?: bean.EndDate
                            //存储数据库
                            taskAssetDao.add(bean)
                            stockTakeListAsset2(bean, userId!!, companyId!!, code)

                            if (index == data.size - 1){
                                listAssetBean2.postValue(DataBean(Code = code, TotalNum = total))
                            }
                        }
                    }
                }
            }

        }, {
            //请求失败 网络异常回调在这里
            loadingChange.dismissDialog
            ToastUtils.showShort(it.throwable!!.message)
            LogUtils.e(it.throwable)
        }, false)

         return false
    }


    private fun stockTakeListAsset2(
        bean: TaskAssetBean,
        userId: String,
        companyID: String,
        code: String?
    ) :Boolean{
        var stocktakeno = bean.Stocktakeno!!
        requestNoCheck({ apiService.stockTakeListAsset(stocktakeno, code!!) }, {
            val json = JSONObject(it.string())
            if (json.optInt("code") == REQUEST_SUCCESS) {
                val data = json.optJSONArray("data")
                if (data != null) {
                    disposable = Flowable.range(0, data.length())
                        .onBackpressureBuffer()
                        .flatMap({ index ->
                            val jsonObject = data.optJSONObject(index)
                            val just = Flowable.just(jsonObject)
                            just.flatMap({ jsonObject ->
                                val tag = jsonObject.optJSONObject("Tag")
                                val inventory = jsonObject.optJSONObject("Inventory")
                                val bean = AssetBean()

                                val pair = Pair(jsonObject, bean)
                                Flowable.fromCallable {
                                    val jsonObject = pair.first as JSONObject
                                    val bean = pair.second as AssetBean
                                    bean.id = tag.optString("userId")
                                    bean.OrderRoNo = stocktakeno
                                    bean.AssetNo = tag.optString("AssetNo")
                                    bean.LabelTag = tag.optString("LabelTag")
                                    bean.Remarks = tag.optString("remarks")
                                    bean.InventoryStatus = tag.optInt("InventoryStatus")
                                    bean.code = code!!
                                    if (inventory != null){
                                        bean.scanStatus = inventory.optInt("FoundStatus")
                                    }
                                    bean.userId = userId
                                    bean.companyId = companyID

                                    bean.data = jsonObject.toString()

                                    bean
                                }.subscribeOn(Schedulers.io())
                            }, true, 1)
                        })
                        .subscribe { bean ->
                            viewModelScope.launch {
                                assetDao.add(bean)
                            }
                        }

                }
            }
        }, {
            //请求失败 网络异常回调在这里
            loadingChange.dismissDialog
            ToastUtils.showShort(it.throwable!!.message)
            LogUtils.e(it.throwable)
        }, false)

        return false
    }

     fun onStockListRequest2(code: String?, total: Int) {
        requestNoCheck({ apiService.getStockTakeList(code!!) }, {
            if (it.code == REQUEST_SUCCESS){
                val data = it.data
                if (data != null){
                    viewModelScope.launch(Dispatchers.IO) {
                        data.forEachIndexed(){index, bean ->
                            bean.id = bean.userId
                            bean.userId = userId
                            bean.companyId = companyId
                            bean.code = code
                            taskStockDao.add(bean)
                            getStockTakeDetail2(bean.OrderNo!!, userId!!, companyId!!, code)
                            if (index == data.size - 1){
                                listStockBean2.postValue(DataBean(Code = code, TotalNum = total))
                            }
                        }
                    }
                }
            }

        }, {
            //请求失败 网络异常回调在这里
            loadingChange.dismissDialog
            ToastUtils.showShort(it.throwable!!.message)
            LogUtils.e(it.throwable)
        }, false)
    }

    private fun getStockTakeDetail2(
        stocktakeno: String,
        userId: String,
        companyID: String,
        code: String?
    ) {
        requestNoCheck({ apiService.getStockTakeDetail(stocktakeno!!, code!!) }, {
            val json = JSONObject(it.string())
            if (json.optInt("code") == REQUEST_SUCCESS) {
                val data = json.optJSONObject("data")
                viewModelScope.launch(Dispatchers.IO) {
                    if (data != null){
                        val datalist = data.optJSONArray("datalist")
                        if (datalist != null && datalist.length() != 0) {
                            for (i in 0 until datalist.length()) {
                                val obj = datalist.optJSONObject(i)
                                obj.put("userId", userId)
                                obj.put("companyId", companyID)
                                obj.put("code", code)

                                val listStr = ArrayList<DataBean>()
                                val attributes = obj.optJSONObject("Attributes")
                                if (attributes != null){
                                    val keys: Iterator<String> = attributes.keys()
                                    while (keys.hasNext()) {
                                        var key = keys.next()
                                        val value: String = attributes.getString(key)
                                        val bean = DataBean()
                                        if (key.contains("InStorage-")) {
                                            key = key.substring(10)
                                        } else if (key.contains("OutStorage-")) {
                                            key = key.substring(11)
                                        }
                                        bean.Title = key
                                        bean.content = value
                                        listStr.add(bean)
                                    }
                                }
                                obj.put("content", Gson().toJson(listStr).toString())
                                val taskStockListBean = Gson().fromJson(obj.toString(), TaskStockListBean::class.java)
                                taskStockListDao.add(taskStockListBean)
                            }

                        }
                    }
                }
            }
        }, {
            //请求失败 网络异常回调在这里
            loadingChange.dismissDialog
            ToastUtils.showShort(it.throwable!!.message)
            LogUtils.e(it.throwable)
        }, false)
    }

}